<template>
  <view class="scroller-content">
    <view
      :class="['loading-box flex-center', { loading: status > 1 }]"
      :style="{
        height: `${move}px`,
        opacity: `${Math.abs(move / maxPull)}`,
      }"
    >
      <view v-show="status === 2" class="loading-icon flex-center">
        <image
          src=""
        ></image>
        <text>努力加载中...</text>
      </view>
      <text v-if="status === 0">下拉刷新</text>
      <text v-else-if="status === 1">松开刷新</text>
      <text v-else-if="status === 3">加载成功</text>
    </view>
    <view
      class="scrollerbox"
      @touchstart="touchstart"
      @touchmove="touchmove"
      @touchend="touchend"
      ><slot></slot
    ></view>
  </view>
</template>

<script>
export default {
  props: {
    isLoading: {
      type: Boolean,
      required: true
    }
  },
  data () {
    return {
      winHeight: 2000,

      // 滑动距离
      move: 0,

      // 加载区域高度 触发点
      offset: 50,

      // 最大可下拉距离
      maxPull: 160,

      // 是否操作中
      action: false,

      // 0.初始  1.松开可刷新  2.刷新中  3.刷新成功
      status: 0,
    };
  },
  mounted () {
    const systemInfo = uni.getSystemInfoSync();
    if (systemInfo && systemInfo.screenHeight) {
      this.winHeight = systemInfo.screenHeight;
    }
  },
  watch: {
    isLoading (newVal) {
      // 父级传递刷新
      if (newVal) {
        this.status = 2;
        this.move = this.offset;
      } else {
        // 不刷新回弹动画
        this.status = 3;
        // 加载成功，露出350ms
        setTimeout(() => {
          this.close();
        }, 350);
      }
    }
  },
  methods: {
    touchstart (ev) {
      if (this.action) return;
      this.startY = ev.changedTouches[ 0 ].clientY;
    },
    touchmove (ev) {
      const { startY, winHeight, offset, maxPull } = this;

      const diffY = ev.changedTouches[ 0 ].clientY - startY;

      if (diffY < 0) return;

      // 阻尼算法 正弦函数0-90°段 0-1之间
      const rate = Math.sin(Math.PI * 0.5 * (diffY / winHeight));
      const move = maxPull * rate;

      this.move = move;
      this.status = move < offset ? 0 : 1;
    },
    touchend () {
      uni.createSelectorQuery().selectViewport().scrollOffset(res => {
        console.log("竖直滚动位置,", res.scrollTop, res);
        console.log("offset,", this.offset);
        console.log("move,", this.move);
        if (res.scrollTop > 500) {
          this.close();
          return;
        };

        if (this.move > this.offset) {
          this.$emit('refresh');
          this.move = this.offset;
        } else {
          this.close();
        }
      }).exec();
    },
    close () {
      this.move = 0;
      this.action = false;
      this.status = 2;
      // 动画完成以后重置
      setTimeout(() => {
        this.status = 0;
      }, 300);
    },
    // 手动触发下拉刷新
    refresh () {
      this.status = 2;
      this.move = 100;

      setTimeout(() => {
        this.status = 3;
        // 加载成功，露出350ms
        setTimeout(() => {
          this.close();
        }, 350);
      }, 300);
    }
  }
};
</script>

<style lang="scss" scoped>
.flex-center {
  display: flex;
  align-items: center;
  justify-content: center;
}

.loading-box {
  &.loading {
    transition: height 0.3s;
  }
  image {
    width: 32rpx;
    height: 32rpx;
    animation: rightSpin 2s linear infinite both;
  }
  text {
    margin-left: 4px;
    font-size: 30rpx;
    color: #666;
    text-shadow: 1rpx 1rpx 4rpx #fff;
  }
}
@keyframes rightSpin {
  from {
    transform: rotate(0deg);
  }
  to {
    transform: rotate(360deg);
  }
}
.scroller-content::-webkit-scrollbar {
  display: none !important;
  width: 0 !important;
  height: 0 !important;
  -webkit-appearance: none;
  background: transparent;
}
</style>
